package com.bjb.vr.remote.ws.rabbitmq.handler.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.MPJMappingWrapper;
import com.bjb.vr.common.constant.AliOssConstants;
import com.bjb.vr.common.constant.RemoteContants;
import com.bjb.vr.common.dto.*;
import com.bjb.vr.common.service.ResDeviceService;
import com.bjb.vr.common.service.ResGroupService;
import com.bjb.vr.common.service.SysUpgradeDevLogService;
import com.bjb.vr.common.service.SysUpgradeService;
import com.bjb.vr.common.utils.AliyunOssUtil;
import com.bjb.vr.common.utils.DateTimeUtil;
import com.bjb.vr.common.utils.RedisUtil;
import com.bjb.vr.remote.properties.ServerInfoProperties;
import com.bjb.vr.remote.ws.rabbitmq.constants.MessageActionConstants;
import com.bjb.vr.remote.ws.rabbitmq.entity.RabbitWebSocketMsg;
import com.bjb.vr.remote.ws.rabbitmq.handler.MessageHandler;
import com.bjb.vr.remote.ws.rabbitmq.utils.Callback;
import com.bjb.vr.remote.ws.rabbitmq.utils.OkHttpDownloader;
import com.bjb.vr.remote.ws.rabbitmq.utils.OkHttpUtil;
import com.bjb.vr.remote.ws.redis.constants.RedisConstants;
import com.bjb.vr.remote.ws.websocket.entity.Action;
import com.bjb.vr.remote.ws.websocket.entity.Command;
import com.bjb.vr.remote.ws.websocket.vo.Message;
import com.bjb.vr.remote.ws.websocket.websocket.WebSocketMsgHandler;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Date;

/**
 * @version 1.0.0
 * @description:设备大厅升级
 * @author: caihaibo
 * @createDate: 2022/7/29
 */
@Slf4j
@Component
public class VRApkUpdateMessageHandler implements MessageHandler {

    @Resource
    private ServerInfoProperties serverInfoProperties;

    @Autowired
    ResDeviceService resDeviceService;

    @Autowired
    SysUpgradeDevLogService sysUpgradeDevLogService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    SysUpgradeService sysUpgradeService;

    final String  LOCK_KEY = "res_dev_sys_update_id";

    @Override
    @Transactional
    public void process(RabbitWebSocketMsg rabbitWebSocketMsg) {
        String dbLockKey = RedisConstants.WEBSOCKET_DB_OP_LOCK_KEY + LOCK_KEY+ rabbitWebSocketMsg.getGroupCode();

        JSONObject jsonObject = JSONObject.parseObject(rabbitWebSocketMsg.getMsg());

        Message message = JSONObject.toJavaObject(jsonObject, Message.class);

        if(message.getAction().equals(MessageActionConstants.MESSAGE_ACTION_VR_APK_UPDATE)){
            log.info("头盔大厅升级消息");
            JSONObject _jsonObject = JSONObject.parseObject(message.getCommand().getParameter());
            long sysUpdateId = _jsonObject.getLong("sysUpdateId");
            String value = String.valueOf(System.currentTimeMillis());
            if (redisUtil.lock(dbLockKey, value, RedisConstants.WEBSOCKET_DB_OP_LOCK_KEY_EXPIRE_TIME)) {
                LambdaQueryWrapper<SysUpgradeDevLog> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(SysUpgradeDevLog::getSysUpdateId,sysUpdateId);
                //获取本次升级设备数
                int count = sysUpgradeDevLogService.count(lambdaQueryWrapper);
                UpdateWrapper<SysUpgrade> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id",sysUpdateId);
                updateWrapper.set("complete", RemoteContants.APK_UPDATE_COMPETE);
                sysUpgradeService.update(updateWrapper);
                if(count ==0 && sysUpdateId!=0) {
                    if(serverInfoProperties.getDeployMode().equals(RemoteContants.DEPLOY_MODE_LOCAL)) {
                        //下载大厅包到本地
                        SysUpgrade sysUpgrade = sysUpgradeService.getById(sysUpdateId);
                        log.info(" 开始下载升级包到本地 " + sysUpgrade.getServerUrl());
                        AliyunOssUtil ossUtil = new AliyunOssUtil.Builder().build(AliOssConstants.ENDPOINT, AliOssConstants.ACCESS_KEY_ID, AliOssConstants.ACCESS_KEY_SECRET);
                        String downLoadUrl = ossUtil.getFileUrl(sysUpgrade.getServerUrl());
//                        OkHttpUtil.builder().downloadFileByUrl(downLoadUrl, serverInfoProperties.getFileUploadPath(), sysUpgrade.getServerUrl());
                        new OkHttpDownloader(downLoadUrl,serverInfoProperties.getFileUploadPath()+ File.separator +  sysUpgrade.getServerUrl()).download(new Callback() {
                            @Override
                            public void onProgress(long progress) {
                                //log.info("下载进度 " +    progress  + " sysUpdateId " + sysUpdateId +  " tenantId " + rabbitWebSocketMsg.getTenantId());
                                redisUtil.set(RedisConstants.APK_UPGRADE_DOWNLOAD_PROGRESS_KEYS + rabbitWebSocketMsg.getTenantId() + "-" + sysUpdateId,Long.valueOf(progress),RedisConstants.DEFAULT_EXPIRE_TIME);
                            }

                            @Override
                            public void onFinish() {
                                log.info("下载完成  sysUpdateId " + sysUpdateId +  " tenantId " + rabbitWebSocketMsg.getTenantId());
                            }

                            @Override
                            public void onError(IOException ex) {
                                log.info("下载出错  sysUpdateId " + sysUpdateId +  " tenantId " + rabbitWebSocketMsg.getTenantId(),ex);
                            }
                        });
                    }
                    log.info("调用batchUpdateResDeviceSysUpdateId ");
                    //更新设备升级状态为需要升级
                    resDeviceService.batchUpdateResDeviceSysUpdateId(rabbitWebSocketMsg.getGroupCode(), sysUpdateId, rabbitWebSocketMsg.getTenantId());
                    //插入升级设备记录
                    sysUpgradeDevLogService.initSysUpGradeDevLog(rabbitWebSocketMsg.getGroupCode(), rabbitWebSocketMsg.getTenantId(), sysUpdateId);
                }


                redisUtil.unlock(dbLockKey, value);
            }

            //发送重启命令
            Action action = new Action();
            action.setAction(MessageActionConstants.MESSAGE_ACTION_RESTART_VR);
            Command command = new Command<>();
            action.setCommand(command);
            rabbitWebSocketMsg.setMsg(JSONObject.toJSONString(action));
            WebSocketMsgHandler.sendAllClient(rabbitWebSocketMsg);
            //设置为空消息，防止其他handler处理
            action.setAction(MessageActionConstants.MESSAGE_ACTION_EMPTY);
            rabbitWebSocketMsg.setMsg(JSONObject.toJSONString(action));
        }
    }
}
